﻿using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using DotNet.DevOps.Tasks.Util;
using Microsoft.Build.Framework;

namespace DotNet.DevOps.Tasks.Log4Net
{
    public interface ILogger
    {
        string Name { get; set; }
        string Files { get; set; }
        string Level { get; set; }
    }

    /// <summary>
    /// Updates the log level of a Log4Net logger element, defined in a log4net configuration file.
    /// </summary>
    /// <example>
    /// import-module .\DotNet.DevOps.Tasks.dll
    /// 
    /// $task = New-Object DotNet.DevOps.Tasks.Log4Net.Logger -Property @{
    ///                                                             Files="log4net.config" 
    ///                                                             Name="NHibernate" 
    ///                                                             Level="WARN" 
    ///                                                        }
    /// $result = $task.Execute()
    /// </example>
    /// <example>
    /// <Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    /// 
    ///  <Import Project="$(libs)\DotNet.DevOps.Tasks.Targets" />
    /// 
    ///  <Target Name="Build">
    /// 
    ///    <Logger Files="log4net.config" Logger="Domain" Level="WARN" />
    ///    <Logger Files="log4net.config" Logger="NServiceBus" Level="WARN" />
    ///    <Logger Files="log4net.config" Logger="NHibernate" Level="WARN" />
    /// 
    ///  </Target>
    /// 
    /// </Project>
    /// </example>   
    public class Logger : BaseLevelUpdater, ITask, ILogger
    {
        /// <summary>
        /// Name of the logger to update.
        /// </summary>
        [Required]
        public string Name { get; set; }

        public IBuildEngine BuildEngine { get; set; }
        public ITaskHost HostObject { get; set; }

        public Logger()
            : base("logger", "name", "level")
        {
            Log = new MSBuildLogger(this);
        }

        public Logger(ILog logger)
            : base("logger", "name", "level")
        {
            Log = logger;
        }

        protected override IEnumerable<XElement> GetMatchingNodes(XDocument xDoc)
        {
            return xDoc.Root.DescendantNodes().OfType<XElement>()
                                    .Where(e => e.Name.ToString().ToLower() == this.NodeName)
                                        .Where(e => e.Attributes().Where(atr => atr.Name.ToString().ToLower() == "name" && atr.Value == Name).Count() > 0);
        }
    }
}
